#include "MyURB.h"

extern const char *PacketNames[];

void MY_URB::DeserializeHeader(unsigned char packType)
{
	packetName = PacketNames[packType];

    buffer.Read(&Hdr.Length,           sizeof(Hdr.Length));
    buffer.Read(&Hdr.Function,         sizeof(Hdr.Function));
    buffer.Read(&Hdr.Status,           sizeof(Hdr.Status));
    buffer.Read(&Hdr.UsbdDeviceHandle, sizeof(Hdr.UsbdDeviceHandle));
    buffer.Read(&Hdr.UsbdFlags,        sizeof(Hdr.UsbdFlags));
    buffer.Read(&isCompleted, sizeof(isCompleted));
}

void MY_URB_WITH_TRANSFER_BUFFER::DeserializeTransferBuffer()
{
    buffer.Read(&thereIsAnMDL, sizeof(thereIsAnMDL));
    buffer.Read(&TransferBufferLength, sizeof(TransferBufferLength));
    if (thereIsAnMDL)
    {
        TransferBufferMDL = std::auto_ptr<char> (new char[TransferBufferLength]);
        buffer.Read(TransferBufferMDL.get(), TransferBufferLength);
        return;
    }
    TransferBuffer  = std::auto_ptr<char> (new char[TransferBufferLength]);
    buffer.Read(TransferBuffer.get(), TransferBufferLength);
}

void MY_URB_SELECT_INTERFACE::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    unsigned short i;
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&ConfigurationHandle, sizeof(ConfigurationHandle));

    buffer.Read(&Interface.Length,           sizeof(Interface.Length));
    buffer.Read(&Interface.InterfaceNumber,  sizeof(Interface.InterfaceNumber));
    buffer.Read(&Interface.AlternateSetting, sizeof(Interface.AlternateSetting));
    buffer.Read(&Interface.Class,            sizeof(Interface.Class));
    buffer.Read(&Interface.SubClass,         sizeof(Interface.SubClass));
    buffer.Read(&Interface.Protocol,         sizeof(Interface.Protocol));
    buffer.Read(&Interface.InterfaceHandle,  sizeof(Interface.InterfaceHandle));
    buffer.Read(&Interface.NumberOfPipes,    sizeof(Interface.NumberOfPipes));

    Interface.Pipes = std::auto_ptr<MY_USBD_PIPE_INFORMATION>
                      (new MY_USBD_PIPE_INFORMATION[Interface.NumberOfPipes]);
    MY_USBD_PIPE_INFORMATION *Pipes = Interface.Pipes.get();
    for (i=0; i<Interface.NumberOfPipes; ++i)
    {
        buffer.Read(&Pipes[i].MaximumPacketSize,   sizeof(Pipes[i].MaximumPacketSize));
        buffer.Read(&Pipes[i].EndpointAddress,     sizeof(Pipes[i].EndpointAddress));
        buffer.Read(&Pipes[i].Interval,            sizeof(Pipes[i].Interval));
        buffer.Read(&Pipes[i].PipeType,            sizeof(Pipes[i].PipeType));
        buffer.Read(&Pipes[i].PipeHandle,          sizeof(Pipes[i].PipeHandle));
        buffer.Read(&Pipes[i].MaximumTransferSize, sizeof(Pipes[i].MaximumTransferSize));
        buffer.Read(&Pipes[i].PipeFlags,           sizeof(Pipes[i].PipeFlags));
    }
}

MY_URB_SELECT_CONFIGURATION::MY_URB_SELECT_CONFIGURATION()
{
    ConfigurationDescriptor.bLength             = 0;
    ConfigurationDescriptor.bDescriptorType     = 0;
    ConfigurationDescriptor.wTotalLength        = 0;
    ConfigurationDescriptor.bNumInterfaces      = 0;
    ConfigurationDescriptor.bConfigurationValue = 0;
    ConfigurationDescriptor.iConfiguration      = 0;
    ConfigurationDescriptor.bmAttributes        = 0;
    ConfigurationDescriptor.MaxPower            = 0;
}

void MY_URB_SELECT_CONFIGURATION::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    unsigned short i, j;
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&bConfigurationDescriptor, sizeof(bConfigurationDescriptor));
    if(!bConfigurationDescriptor)
    {
        buffer.Read(&ConfigurationHandle, sizeof(ConfigurationHandle));
        return;
    }
    
    MY_USB_CONFIGURATION_DESCRIPTOR *pConfD = &ConfigurationDescriptor;
    buffer.Read(&pConfD->bLength,             sizeof(pConfD->bLength));
    buffer.Read(&pConfD->bDescriptorType,     sizeof(pConfD->bDescriptorType));
    buffer.Read(&pConfD->wTotalLength,        sizeof(pConfD->wTotalLength));
    buffer.Read(&pConfD->bNumInterfaces,      sizeof(pConfD->bNumInterfaces));
    buffer.Read(&pConfD->bConfigurationValue, sizeof(pConfD->bConfigurationValue));
    buffer.Read(&pConfD->iConfiguration,      sizeof(pConfD->iConfiguration));
    buffer.Read(&pConfD->bmAttributes,        sizeof(pConfD->bmAttributes));
    buffer.Read(&pConfD->MaxPower,            sizeof(pConfD->MaxPower));

    Interface = std::auto_ptr<MY_USBD_INTERFACE_INFORMATION>
                (new MY_USBD_INTERFACE_INFORMATION[pConfD->bNumInterfaces]);
    MY_USBD_INTERFACE_INFORMATION *pInterface = Interface.get();
    for (i=0; i<pConfD->bNumInterfaces; ++i)
    {
        buffer.Read(&pInterface[i].Length,           sizeof(pInterface[i].Length));
        buffer.Read(&pInterface[i].InterfaceNumber,  sizeof(pInterface[i].InterfaceNumber));
        buffer.Read(&pInterface[i].AlternateSetting, sizeof(pInterface[i].AlternateSetting));
        buffer.Read(&pInterface[i].Class,            sizeof(pInterface[i].Class));
        buffer.Read(&pInterface[i].SubClass,         sizeof(pInterface[i].SubClass));
        buffer.Read(&pInterface[i].Protocol,         sizeof(pInterface[i].Protocol));
        buffer.Read(&pInterface[i].InterfaceHandle,  sizeof(pInterface[i].InterfaceHandle));
        buffer.Read(&pInterface[i].NumberOfPipes,    sizeof(pInterface[i].NumberOfPipes));
        
        pInterface[i].Pipes = std::auto_ptr<MY_USBD_PIPE_INFORMATION>
                              (new MY_USBD_PIPE_INFORMATION[pInterface[i].NumberOfPipes]);
        MY_USBD_PIPE_INFORMATION *Pipes = pInterface[i].Pipes.get();
        for (j=0; j<pInterface[i].NumberOfPipes; ++j)
        {
            buffer.Read(&Pipes[j].MaximumPacketSize,   sizeof(Pipes[j].MaximumPacketSize));
            buffer.Read(&Pipes[j].EndpointAddress,     sizeof(Pipes[j].EndpointAddress));
            buffer.Read(&Pipes[j].Interval,            sizeof(Pipes[j].Interval));
            buffer.Read(&Pipes[j].PipeType,            sizeof(Pipes[j].PipeType));
            buffer.Read(&Pipes[j].PipeHandle,          sizeof(Pipes[j].PipeHandle));
            buffer.Read(&Pipes[j].MaximumTransferSize, sizeof(Pipes[j].MaximumTransferSize));
            buffer.Read(&Pipes[j].PipeFlags,           sizeof(Pipes[j].PipeFlags));
        }
    }
    buffer.Read(&ConfigurationHandle, sizeof(ConfigurationHandle));
}

void MY_URB_PIPE_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle, sizeof(PipeHandle));
}

void MY_URB_GET_CURRENT_FRAME_NUMBER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&FrameNumber, sizeof(FrameNumber));
}

void MY_URB_CONTROL_TRANSFER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
    buffer.Read(SetupPacket, sizeof(SetupPacket));
}
void MY_URB_CONTROL_TRANSFER_EX::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
    buffer.Read(&Timeout,    sizeof(Timeout));
    buffer.Read(SetupPacket, sizeof(SetupPacket));
}

void MY_URB_BULK_OR_INTERRUPT_TRANSFER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    
    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
}

void MY_URB_ISOCH_TRANSFER::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    unsigned short i;
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&PipeHandle,    sizeof(PipeHandle));
    buffer.Read(&TransferFlags, sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);

    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }

    buffer.Read(&StartFrame,      sizeof(StartFrame));
    buffer.Read(&NumberOfPackets, sizeof(NumberOfPackets));
    buffer.Read(&ErrorCount,      sizeof(ErrorCount));

    IsoPacket = std::auto_ptr<MY_USBD_ISO_PACKET_DESCRIPTOR>
                              (new MY_USBD_ISO_PACKET_DESCRIPTOR[NumberOfPackets]);
    MY_USBD_ISO_PACKET_DESCRIPTOR *pIsoPacket = IsoPacket.get();
    for (i=0; i<NumberOfPackets; ++i)
    {
        buffer.Read(&pIsoPacket[i].Offset, sizeof(pIsoPacket[i].Offset));
        buffer.Read(&pIsoPacket[i].Length, sizeof(pIsoPacket[i].Length));
        buffer.Read(&pIsoPacket[i].Status, sizeof(pIsoPacket[i].Status));
    }
}

void MY_URB_CONTROL_DESCRIPTOR_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    DeserializeTransferBuffer();

    buffer.Read(&Index,          sizeof(Index));
    buffer.Read(&DescriptorType, sizeof(DescriptorType));
    buffer.Read(&LanguageId,     sizeof(LanguageId));
}

void MY_URB_CONTROL_GET_STATUS_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);	
    DeserializeTransferBuffer();

    buffer.Read(&Index, sizeof(Index));
}

void MY_URB_CONTROL_FEATURE_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&FeatureSelector, sizeof(FeatureSelector));
    buffer.Read(&Index,           sizeof(Index));
}

void MY_URB_CONTROL_VENDOR_OR_CLASS_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);

    buffer.Read(&TransferFlags,	sizeof(TransferFlags));

    bool dataIsRequestedFromDevice = (bool)(TransferFlags & 1);
    if(((!dataIsRequestedFromDevice) && (!isCompleted)) || (dataIsRequestedFromDevice && isCompleted))
    {
        DeserializeTransferBuffer();
    }
    buffer.Read(&RequestTypeReservedBits, sizeof(RequestTypeReservedBits));

    buffer.Read(&Request, sizeof(Request));
    buffer.Read(&Value,   sizeof(Value));
    buffer.Read(&Index,   sizeof(Index));
}

void MY_URB_CONTROL_GET_INTERFACE_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    DeserializeTransferBuffer();

    buffer.Read(&Interface, sizeof(Interface));
}

void MY_URB_CONTROL_GET_CONFIGURATION_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    DeserializeTransferBuffer();
}

void MY_URB_OS_FEATURE_DESCRIPTOR_REQUEST::Deserialize (void *pBuffer, long bufSize, unsigned char packType)
{
    buffer.SetBuffer(pBuffer, bufSize);
    DeserializeHeader(packType);
    DeserializeTransferBuffer();

    buffer.Read(&Recipient,                 sizeof(Recipient));
    buffer.Read(&InterfaceNumber,           sizeof(InterfaceNumber));
    buffer.Read(&MS_PageIndex,              sizeof(MS_PageIndex));
    buffer.Read(&MS_FeatureDescriptorIndex, sizeof(MS_FeatureDescriptorIndex));
}